page.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import { Metadata } from 'next';
  2. import { notFound } from 'next/navigation';
  3. import { allDocs } from 'contentlayer/generated';
  4. import { name } from '@/config/site';
  5. import { getTableOfContents } from '@/lib/toc';
  6. import Mdx from '@/components/MDX';
  7. import TablerSponsorsBanner from '@/components/TablerSponsorsBanner';
  8. import Link from 'next/link';
  9. import TOC from '@/components/TOC';
  10. import DocsMenu from '@/components/DocsMenu';
  11. import Icon from '@/components/Icon';
  12. interface DocPageProps {
  13. params: {
  14. slug: string[]
  15. }
  16. }
  17. async function getDocFromParams(params) {
  18. const slug = params.slug?.join('/') || '';
  19. const doc = allDocs.find((doc) => doc.slugAsParams === slug);
  20. if (!doc) {
  21. null;
  22. }
  23. return doc;
  24. }
  25. export async function generateMetadata({
  26. params,
  27. }: DocPageProps): Promise<Metadata> {
  28. const doc = await getDocFromParams(params);
  29. if (!doc) {
  30. return {};
  31. }
  32. return {
  33. title: `${doc.title} - Documentation - ${name}`,
  34. description: doc.description,
  35. openGraph: {
  36. type: 'article',
  37. },
  38. };
  39. }
  40. export async function generateStaticParams(): Promise<
  41. DocPageProps['params'][]
  42. > {
  43. return allDocs.map((doc) => ({
  44. slug: doc.slugAsParams.split('/'),
  45. }));
  46. }
  47. export default async function DocPage({ params }: DocPageProps) {
  48. const doc = await getDocFromParams(params);
  49. if (!doc) {
  50. notFound();
  51. }
  52. const toc = await getTableOfContents(doc.body.raw);
  53. return (
  54. <div className="row g-0">
  55. <div className="md:col-auto docs-side">
  56. {/*<input type="search" className="form-control w-100 mb-5" placeholder="Search&hellip;" />*/}
  57. <DocsMenu />
  58. </div>
  59. <div className="md:col">
  60. <div className="py-6 md:pl-6">
  61. <nav aria-label="breadcrumbs" className="breadcrumb mb-6">
  62. <ul className="breadcrumb-list">
  63. <li className="breadcrumb-item">
  64. <Link href="/" className="breadcrumb-link">
  65. Home
  66. </Link>
  67. </li>
  68. <li className="breadcrumb-item">
  69. <Link href="/docs" className="breadcrumb-link">
  70. Documentation
  71. </Link>
  72. </li>
  73. <li className="breadcrumb-item">
  74. <Link href={`/docs/${params.slug.join('/')}`} className="breadcrumb-link">
  75. {doc.title}
  76. </Link>
  77. </li>
  78. </ul>
  79. </nav>
  80. <div className="markdown">
  81. {/* {category && (
  82. <div className="h-subheader text-primary">{category}</div>
  83. )} */}
  84. {doc.title && <h1>{doc.title}</h1>}
  85. {doc.description && <p className="lead">{doc.description}</p>}
  86. <Mdx code={doc.body.code} />
  87. </div>
  88. <TablerSponsorsBanner className="mt-7" />
  89. </div>
  90. </div>
  91. <div className="docs-side-toc">
  92. <div className="pl-6 font-h6 pt-6">
  93. <div className="h6 mb-3">On this page</div>
  94. <div>
  95. <TOC toc={toc} />
  96. </div>
  97. <div className="mt-4 border-top pt-4">
  98. <a href={`https://github.com/tabler/tabler/blob/main/docs/${doc.slugAsParams.split(',').join('/')}.mdx`} className="link-muted">
  99. Improve this page
  100. <Icon name="edit" className="icon-inline ml-2" />
  101. </a>
  102. </div>
  103. </div>
  104. </div>
  105. </div>
  106. );
  107. }